package com.mtiiot.fstcpserver.base;

import com.mtiiot.fscore.bean.MetadataInfo;
import com.mtiiot.fscore.bean.MqInfo;
import com.mtiiot.fscore.bean.elasticsearch.metadata.BaseBean;
import com.mtiiot.fscore.bean.elasticsearch.metadata.LogMetadata;
import com.mtiiot.fscore.utils.LogLevel;
import com.mtiiot.fscore.utils.RequestType;
import com.mtiiot.fscore.utils.StringUtil;
import com.mtiiot.fstcpserver.es.BaseElasticsearch;
import com.mtiiot.fstcpserver.mq.kafka.insplatform.InstruProducer;
import com.mtiiot.fstcpserver.utils.Constants;
import com.mtiiot.fstcpserver.utils.FsConfig;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisCluster;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by lcy on 16-8-10.
 */
public class BaseService {
    private static final Logger logger = LogManager.getLogger(BaseService.class);

    //    @Autowired
    //    private RedisShardBase redisShardBase;
    @Autowired
    private JedisCluster jedisCluster;

    @Autowired
    private FsConfig fsConfig;

    @Autowired
    private BaseElasticsearch baseElasticsearch;

//    public RedisShardBase getRedisShardBase() {
//        return redisShardBase;
//    }
//
//    public void setRedisShardBase(RedisShardBase redisShardBase) {
//        this.redisShardBase = redisShardBase;
//    }

    public JedisCluster getJedisCluster() {
        return jedisCluster;
    }

    public void setJedisCluster(JedisCluster jedisCluster) {
        this.jedisCluster = jedisCluster;
    }

    public FsConfig getFsConfig() {
        return fsConfig;
    }

    public void setFsConfig(FsConfig fsConfig) {
        this.fsConfig = fsConfig;
    }

    public void handleException(String l1,String l2,String l3,Exception ex,Logger logger){
        //异常信息 元数据入reids队列
        try{
            logger.error(ex);
            ObjectMapper mapper = new ObjectMapper();
            LogMetadata md=new LogMetadata();
            md.setId(StringUtil.getUUID());
            Date d=new Date();
            Calendar cc = Calendar.getInstance();
            cc.setTime(d);
            md.setTime(d);
            md.setShowTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d));
            md.setYear(cc.get(Calendar.YEAR));
            md.setMonth(cc.get(Calendar.MONTH)+1);
            md.setDay(cc.get(Calendar.DATE));
            md.setSysId(Constants.SYS_ID_FS);
            String sysName="";
            try{
                sysName=jedisCluster.hget(Constants.SYSINFO_REDISKEY_001,Constants.SYS_ID_FS);
            }catch (Exception exx){
                logger.error(ex.getMessage(),exx);
                sysName="fs";
            }
            md.setSysName(sysName);
            md.setL1Name(l1);//fs的哪个模块
            md.setL2Name(l2);//类名
            md.setL3Name(l3);//方法名
            md.setRequestType(RequestType.INSERT.getName());
            if(ex==null||ex.getMessage()==null||ex.getMessage().equals("")){
                md.setKeyValue("excption is empty");
                md.setRequestSize(0.0);
            }else{
                md.setKeyValue(ex.getClass().getName());
                md.setRequestSize(StringUtil.bytes2kbDouble(ex.getMessage().getBytes().length));
            }
            md.setHost(fsConfig.getFsHost());
            md.setLogLevel(LogLevel.ERROR.getName());
            if(ex==null||ex.getMessage()==null||ex.getMessage().equals("")){
                md.setMessage("");
            }else{
                md.setMessage(ex.getMessage());
            }

//            MqInfo mqTmp=new MqInfo();
//            mqTmp.setTopic(Constants.TOPIC_METADATAINFO);
//            mqTmp.setKey(Constants.TYPE_METADATA_LOG);
//            mqTmp.setValue(md);
//            String json=mapper.writeValueAsString(mqTmp);
//            jedisCluster.lpush(Constants.METADATA_REDISKEY_001,json);//1  异步日志异常数据入redis队列

            metadataInQueue(Constants.TOPIC_METADATAINFO,Constants.TYPE_METADATA_LOG,md);
        }catch (Exception e){
            logger.error(ex.getMessage(),e);
        }
    }


    /**
     * 元数据入队列
     * @return
     */
    public void metadataInQueue(String topic,String key,Object bean)throws Exception{
        String inQueueType=fsConfig.getMetadataInQueueType();
        if(Constants.METADATA_IN_QUEUE_TYPE_ES.equals(inQueueType)){
            metadataInES(key,bean);
            return;
        }
        if(Constants.METADATA_IN_QUEUE_TYPE_KAFKA.equals(inQueueType)){
            metadataInKafkaQueue(topic,key,bean);
            return;
        }
        if(Constants.METADATA_IN_QUEUE_TYPE_REDIS.equals(inQueueType)){
            metadataInRedisQueue(topic,key,bean);
            return;
        }
    }

    /**
     * 元数据直接入库
     * @return
     */
    public void metadataInES(String key,Object bean)throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String info=mapper.writeValueAsString(bean);
        ((BaseBean)bean).setRequestSize(StringUtil.bytes2kbDouble(info.getBytes().length));
        info=mapper.writeValueAsString(bean);
        baseElasticsearch.createIndexById(Constants.INDEX_METADATA,key,info,((BaseBean) bean).getId());
    }

    /**
     * 元数据入kafka队列
     * @return
     */
    public void metadataInKafkaQueue(String topic,String key,Object bean)throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String info=mapper.writeValueAsString(bean);
        ((BaseBean)bean).setRequestSize(StringUtil.bytes2kbDouble(info.getBytes().length));
        info=mapper.writeValueAsString(bean);
        InstruProducer.sendData(topic, key, info);
    }

    /**
     * 元数据入redis队列
     * @return
     */
    public void metadataInRedisQueue(String topic,String key,Object bean)throws Exception{
        ObjectMapper mapper = new ObjectMapper();
        String info=mapper.writeValueAsString(bean);
        ((BaseBean)bean).setRequestSize(StringUtil.bytes2kbDouble(info.getBytes().length));
        MqInfo mqTmp=new MqInfo();
        mqTmp.setTopic(topic);
        mqTmp.setKey(key);
        mqTmp.setValue(bean);
        String json=mapper.writeValueAsString(mqTmp);
        jedisCluster.lpush(Constants.METADATA_REDISKEY_001,json);//1  异步日志异常数据入redis队列
    }

    /**
     * 设置元数据bean
     * @param mi
     * @param bean
     * @param requestType
     * @param info
     * @throws Exception
     */
    public void setMetadataBeanData(MetadataInfo mi,BaseBean bean,String requestType,String info)throws Exception{
        Date d=new Date();
        Calendar cc = Calendar.getInstance();
        cc.setTime(d);
        if(StringUtil.isEmpty(bean.getId())){
            bean.setId(StringUtil.getUUID());
        }
        bean.setTime(d);
        bean.setShowTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d));
        bean.setYear(cc.get(Calendar.YEAR));
        bean.setMonth(cc.get(Calendar.MONTH)+1);
        bean.setDay(cc.get(Calendar.DATE));
        bean.setSysId(mi.getSysId());
        String sysName=jedisCluster.hget(Constants.SYSINFO_REDISKEY_001,mi.getSysId());
        bean.setSysName(sysName);
        bean.setL1Name(mi.getL1Name());//fs的哪个模块
        bean.setL2Name(mi.getL2Name());//类名
        bean.setL3Name(mi.getL3Name());//方法名
        bean.setRequestType(requestType);
        bean.setRequestSize(StringUtil.bytes2kbDouble(info.getBytes().length));
        bean.setHost(mi.getHost());
    }

    /**
     * 设置元数据bean
     * @param mi
     * @param bean
     * @param requestType
     * @throws Exception
     */
    public void setMetadataBeanData(MetadataInfo mi,BaseBean bean,String requestType)throws Exception{
        Date d=new Date();
        Calendar cc = Calendar.getInstance();
        cc.setTime(d);
        bean.setId(StringUtil.getUUID());
        bean.setTime(d);
        bean.setShowTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d));
        bean.setYear(cc.get(Calendar.YEAR));
        bean.setMonth(cc.get(Calendar.MONTH)+1);
        bean.setDay(cc.get(Calendar.DATE));
        bean.setSysId(mi.getSysId());
        String sysName=jedisCluster.hget(Constants.SYSINFO_REDISKEY_001,mi.getSysId());
        bean.setSysName(sysName);
        bean.setL1Name(mi.getL1Name());//fs的哪个模块
        bean.setL2Name(mi.getL2Name());//类名
        bean.setL3Name(mi.getL3Name());//方法名
        bean.setRequestType(requestType);
        bean.setHost(mi.getHost());
    }

    /**
     * 设置元数据bean
     * @param mi
     * @param bean
     * @param requestType
     * @throws Exception
     */
    public void setMetadataBeanDataAndId(MetadataInfo mi,BaseBean bean,String requestType, String uuId)throws Exception{
        Date d=new Date();
        Calendar cc = Calendar.getInstance();
        cc.setTime(d);
        bean.setId(uuId);
        bean.setTime(d);
        bean.setShowTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d));
        bean.setYear(cc.get(Calendar.YEAR));
        bean.setMonth(cc.get(Calendar.MONTH)+1);
        bean.setDay(cc.get(Calendar.DATE));
        bean.setSysId(mi.getSysId());
        String sysName=jedisCluster.hget(Constants.SYSINFO_REDISKEY_001,mi.getSysId());
        bean.setSysName(sysName);
        bean.setL1Name(mi.getL1Name());//fs的哪个模块
        bean.setL2Name(mi.getL2Name());//类名
        bean.setL3Name(mi.getL3Name());//方法名
        bean.setRequestType(requestType);
        bean.setHost(mi.getHost());
    }

    public void checkMetadata(MetadataInfo metadataInfo) throws Exception{
        if(metadataInfo==null){
            throw new Exception("元数据为空!");
        }
        if(StringUtil.isEmpty(metadataInfo.getSysId())){
            throw new Exception("系统id为空!");
        }
        String sysName=jedisCluster.hget(Constants.SYSINFO_REDISKEY_001,metadataInfo.getSysId());
        if(StringUtil.isEmpty(sysName)){
            throw new Exception("系统id:"+metadataInfo.getSysId()+",验证失败!");
        }
        if(StringUtil.isEmpty(metadataInfo.getL1Name())){
            metadataInfo.setL1Name(Constants.MYSQLDEFAULT_DEF);
        }
        if(StringUtil.isEmpty(metadataInfo.getL2Name())){
            metadataInfo.setL2Name(Constants.MYSQLDEFAULT_DEF);
        }
        if(StringUtil.isEmpty(metadataInfo.getL3Name())){
            metadataInfo.setL3Name(Constants.MYSQLDEFAULT_DEF);
        }
    }

    public void checkEsIndexAndType(String index,String type) throws Exception{

    }
}
